﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using Castle.ActiveRecord.Framework;
using NHibernate;
using NHibernate.Cfg;
using NUnit.Framework;

namespace LazyTests {
    [TestFixture]
    public class PersistConfig {
        [Test]
        public void ttt() {
            
        }

        public class PersistingSessionFactoryHolder: ISessionFactoryHolder {
            private readonly ISessionFactoryHolder sfHolder = new SessionFactoryHolder();

            public void Register(Type rootType, Configuration cfg) {
                sfHolder.Register(rootType, cfg);
            }

            public Configuration[] GetAllConfigurations() {
                return sfHolder.GetAllConfigurations();
            }

            public Configuration GetConfiguration(Type type) {
                return sfHolder.GetConfiguration(type);
            }

            public ISessionFactory GetSessionFactory(Type type) {
                return sfHolder.GetSessionFactory(type);
            }

            public ISessionFactory[] GetSessionFactories() {
                return sfHolder.GetSessionFactories();
            }

            public ISession CreateSession(Type type) {
                return sfHolder.CreateSession(type);
            }

            public void ReleaseSession(ISession session) {
                sfHolder.ReleaseSession(session);
            }

            public void FailSession(ISession session) {
                sfHolder.FailSession(session);
            }

            public Type GetRootType(Type type) {
                return sfHolder.GetRootType(type);
            }

            public void RegisterSessionFactory(ISessionFactory sessionFactory, Type baseType) {
                sfHolder.RegisterSessionFactory(sessionFactory, baseType);
            }

            public IThreadScopeInfo ThreadScopeInfo {
                get { return sfHolder.ThreadScopeInfo; }
                set { sfHolder.ThreadScopeInfo = value; }
            }

            public event RootTypeHandler OnRootTypeRegistered;
        }

        /// <summary>
        ///   Knows how to read/write an NH <see cref = "Configuration" /> from
        ///   a given filename, and whether that file should be trusted or a new
        ///   Configuration should be built.
        /// </summary>
        /// <see href = "http://github.com/castleproject/Castle.Facilities.NHibernateIntegration/blob/master/src/Castle.Facilities.NHibernateIntegration/Persisters/DefaultConfigurationPersister.cs" />
        public class DefaultConfigurationPersister {
            /// <summary>
            ///   Gets the <see cref = "Configuration" /> from the file.
            /// </summary>
            /// <param name = "filename">The name of the file to read from</param>
            /// <returns>The <see cref = "Configuration" /></returns>
            public virtual Configuration ReadConfiguration(string filename) {
                var formatter = new BinaryFormatter();
                using (var fileStream = new FileStream(filename, FileMode.OpenOrCreate)) {
                    return formatter.Deserialize(fileStream) as Configuration;
                }
            }

            /// <summary>
            ///   Writes the <see cref = "Configuration" /> to the file
            /// </summary>
            /// <param name = "filename">The name of the file to write to</param>
            /// <param name = "cfg">The NH Configuration</param>
            public virtual void WriteConfiguration(string filename, Configuration cfg) {
                var formatter = new BinaryFormatter();
                using (var fileStream = new FileStream(filename, FileMode.OpenOrCreate)) {
                    formatter.Serialize(fileStream, cfg);
                }
            }

            /// <summary>
            ///   Checks if a new <see cref = "Configuration" /> is required or a serialized one should be used.
            /// </summary>
            /// <param name = "filename">Name of the file containing the NH configuration</param>
            /// <param name = "dependencies">Files that the serialized configuration depends on. </param>
            /// <returns>If the <see cref = "Configuration" /> should be created or not.</returns>
            public virtual bool IsNewConfigurationRequired(string filename, IList<string> dependencies) {
                if (!File.Exists(filename))
                    return true;

                var lastModified = File.GetLastWriteTime(filename);
                var requiresNew = false;
                for (var i = 0; i < dependencies.Count && !requiresNew; i++) {
                    var dependencyLastModified = File.GetLastWriteTime(dependencies[i]);
                    requiresNew |= dependencyLastModified > lastModified;
                }
                return requiresNew;
            }
        }
    }
}